// ==========================================================================
// gin-sns自动生成控制器相关代码，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/controller/module/user_api.go
// author：jon
// ==========================================================================
package module

import (
	"gin-sns/app/controller/api/render"
	"gin-sns/app/ginframe/response"
	"gin-sns/app/ginframe/tools"
	"gin-sns/app/model"
	"gin-sns/app/model/constants"
	followModel "gin-sns/app/model/module/follow"
	messageModel "gin-sns/app/model/module/message"
	userModel "gin-sns/app/model/module/user"
	"gin-sns/app/service/module"
	"strings"

	"github.com/gin-gonic/gin"
	//"gin-sns/app/ginframe/utils/gconv"
)

var UserApi = newUserApi()

func newUserApi() *userApi {
	return &userApi{}
}

type userApi struct {
}

//列表分页数据
func (c *userApi) ListAjax(ctx *gin.Context) {
	req := new(userModel.SelectPageReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).Log("user管理", req).WriteJsonExit()
		return
	}
	rows := make([]userModel.Entity, 0)
	result, page, err := module.UserService.SelectListByPage(req)

	if err == nil && len(result) > 0 {
		rows = result
	}

	response.BuildTable(ctx, page.Total, rows).WriteJsonExit()
}

//新增页面保存
func (c *userApi) AddSave(ctx *gin.Context) {
	req := new(userModel.AddReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Add).SetMsg(err.Error()).Log("普通用户新增数据", req).WriteJsonExit()
		return
	}

	id, err := module.UserService.AddSave(req, ctx)

	if err != nil || id <= 0 {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Add).Log("普通用户新增数据", req).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetData(id).Log("普通用户新增数据", req).WriteJsonExit()
}

//修改页面保存
func (c *userApi) EditSave(ctx *gin.Context) {
	req := new(userModel.EditReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Edit).SetMsg(err.Error()).Log("普通用户修改数据", req).WriteJsonExit()
		return
	}

	rs, err := module.UserService.EditSave(req, ctx)

	if err != nil || rs <= 0 {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Edit).Log("普通用户修改数据", req).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetBtype(model.Buniss_Edit).Log("普通用户修改数据", req).WriteJsonExit()
}

//删除数据
func (c *userApi) Remove(ctx *gin.Context) {
	req := new(model.RemoveReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Del).SetMsg(err.Error()).Log("普通用户删除数据", req).WriteJsonExit()
		return
	}

	rs := module.UserService.DeleteRecordByIds(req.Ids)

	if rs > 0 {
		response.SucessResp(ctx).SetBtype(model.Buniss_Del).Log("普通用户删除数据", req).WriteJsonExit()
	} else {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Del).Log("普通用户删除数据", req).WriteJsonExit()
	}
}

// 用户详情
func (c *userApi) GetBy(ctx *gin.Context) {

	userId := ctx.GetInt64("userId") //check it!

	//user := cache.UserCache.Get(userId) //cache 1
	user, err := module.UserService.SelectRecordById(userId) //from db
	if user == nil || err != nil {
		response.ErrorResp(ctx).SetMsg("用户不存在").WriteJsonExit()
		return
	}

	response.SucessResp(ctx).SetData(render.BuildUser(user)).WriteJsonExit()
	return
}

// 修改用户资料
func (c *userApi) PostEditBy(ctx *gin.Context) {
	userId := ctx.GetInt64("userId") //check it!

	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	if user.Id != userId {
		response.ErrorResp(ctx).SetMsg("无权限").WriteJsonExit()
		return
	}
	nickname := strings.TrimSpace(ctx.GetString("nickname"))
	avatar := strings.TrimSpace(ctx.GetString("avatar"))
	description := ctx.GetString("description")

	if len(nickname) == 0 {
		response.ErrorResp(ctx).SetMsg("昵称不能为空").WriteJsonExit()
		return
	}
	if len(avatar) == 0 {
		response.ErrorResp(ctx).SetMsg("头像不能为空").WriteJsonExit()
		return
	}

	user.Nickname = nickname
	user.Avatar = avatar
	user.Description = description

	err := module.UserService.Update(user)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}

	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

//todo

// 修改密码
func (c *userApi) PostUpdatePassword(ctx *gin.Context) {
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	var (
		oldPassword = ctx.GetString("oldPassword")
		password    = ctx.GetString("password")
		rePassword  = ctx.GetString("rePassword")
	)
	err := module.UserService.UpdatePassword(user.Id, oldPassword, password, rePassword)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

// 未读消息数量
func (c *userApi) GetMsgcount(ctx *gin.Context) {
	user := module.UsertokenService.GetCurrent(ctx)
	var count int64 = 0
	if user != nil {
		count, _ = module.MessageService.GetUnReadCount(user.Id)
	}
	response.SucessResp(ctx).SetData(count).WriteJsonExit() //"count", count
	return
}

// 用户收藏

// 用户消息
func (c *userApi) GetMessages(ctx *gin.Context) {

	pageNum := ctx.GetInt("page")

	user := module.UsertokenService.GetCurrent(ctx)
	// 用户必须登录
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	req := new(messageModel.SelectPageReq)
	req.UserId = user.Id //user
	req.PageNum = pageNum

	rows := make([]messageModel.Entity, 0)
	result, page, err := module.MessageService.SelectListByPage(req)

	if err == nil && len(result) > 0 {
		rows = result
	}

	response.BuildTable(ctx, page.Total, rows).WriteJsonExit()

	// 全部标记为已读
	module.MessageService.MarkReadAll(user.Id)
	return
}

//Follow
func (c *userApi) PostFollow(ctx *gin.Context) {
	followId := ctx.GetInt64("followId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	if user.Id == followId {
		response.ErrorResp(ctx).SetMsg("cant not follow yourself").WriteJsonExit()
		return
	}

	req := &followModel.AddReq{}
	req.EntityId = followId
	req.EntityType = constants.EntityTypeUser
	req.UserId = user.Id

	_, err := module.FollowService.AddSave(req, nil)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}

	module.UserService.IncrFollowCount(user.Id)
	module.UserService.IncrFollowedCount(followId)

	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

//unfollow
func (c *userApi) PostUnfollow(ctx *gin.Context) {
	followId := ctx.GetInt64("followId")

	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	if user.Id == followId {
		response.ErrorResp(ctx).SetMsg("cant not follow yourself").WriteJsonExit()
		return
	}

	module.FollowService.DeleteByUserIdAndFollowId(user.Id, followId)

	module.UserService.DecrFollowCount(user.Id)
	module.UserService.DecrFollowedCount(followId)

	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

//get follow
func (c *userApi) GetAllFollow(ctx *gin.Context) {
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	var list []userModel.Entity
	ids, err := module.FollowService.GetUserNewestFollowIds(user.Id, 40)
	if err == nil && ids != nil {
		list, _ = module.UserService.SelectRecordsIn(ids)
	}

	response.SucessResp(ctx).SetData(render.BuildUsers(list)).WriteJsonExit()
	return
}

//get followed
func (c *userApi) GetAllFollowed(ctx *gin.Context) {
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	var list []userModel.Entity
	ids, err := module.FollowService.GetUserNewestFollowedIds(user.Id, 40)
	if err != nil {
		list, _ = module.UserService.SelectRecordsIn(ids)
	}

	response.SucessResp(ctx).SetData(render.BuildUsers(list)).WriteJsonExit()
	return
}
